float4x4 World;
float4x4 View;
float4x4 Projection;

texture DepthMap;
sampler DepthSampler = sampler_state
{
    Texture = (DepthMap);
    MAGFILTER = POINT;
    MINFILTER = POINT;
    MIPFILTER = POINT;
    AddressU = CLAMP;
    AddressV = CLAMP;
};

struct VertexShaderInput
{
    float4 Position         : POSITION0;
    float4 Color            : COLOR0;
};

struct VertexShaderOutput
{
    float4 Position     : POSITION0;
    float4 Screen       : TEXCOORD0;
    float2 Depth        : TEXCOORD1;
    float4 Color        : COLOR0;
};

VertexShaderOutput VertexShaderFunction(VertexShaderInput input)
{
    VertexShaderOutput output;

    float4 worldPosition = mul(float4(input.Position.xyz, 1), World);
    float4 viewPosition = mul(worldPosition, View);
    output.Position = mul(viewPosition, Projection);

    output.Screen = output.Position;
    output.Depth = viewPosition.z;
    output.Color = input.Color;

    return output;
}

float4 PixelShaderFunction(VertexShaderOutput input) : COLOR0
{
	float myDepth = input.Screen.z / input.Screen.w;
    float2 screenCoords = ((input.Screen.xy / input.Screen.w) + 1.0) / 2.0;
    screenCoords.y = 1-screenCoords.y;
    float depthVal = tex2D(DepthSampler, screenCoords).r;

    clip(depthVal - myDepth + 0.0002f); // allow a slight offset so if the 2d is very close to or on a surface its still shown

    return input.Color;
}

technique Technique1
{
    pass Pass1
    {
        VertexShader = compile vs_2_0 VertexShaderFunction();
        PixelShader = compile ps_2_0 PixelShaderFunction();
    }
}
